package practise.mulitThreads.ConcurrentInPractice.secondTime;

import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *  a binary latch, just one, zero switch.
 */
public class BinayLatch {
    AtomicBoolean atomicBoolean = new AtomicBoolean(true);
    Lock lock = new ReentrantLock();
    class Sync extends AbstractQueuedSynchronizer{
        @Override
        protected boolean tryAcquire(int arg) {
            try{
                lock.lock();
                return atomicBoolean.getAndSet(!atomicBoolean.get());
            }
            finally {
                lock.unlock();
            }
        }

        @Override
        protected boolean tryRelease(int arg) {
            try{
                lock.tryLock();
                return atomicBoolean.getAndSet(!atomicBoolean.get());
            }
            finally {
                lock.unlock();
            }
        }
    }
    Sync sync = new Sync();
    public void acquire() throws InterruptedException {
        sync.acquireSharedInterruptibly(0);
    }

    public void release(){
        sync.releaseShared(0);
    }

}
